package com.aco.fatureapp.printer.libs;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.Style;
import android.graphics.Typeface;
import android.os.SystemClock;

import com.aco.fatureapp.model.billing.LogLeitura;
import com.aco.fatureapp.model.printer.Billing;
import com.aco.fatureapp.model.printer.Historic;
import com.aco.fatureapp.model.printer.PrinterResumo;
import com.aco.fatureapp.model.printer.Products;
import com.aco.fatureapp.service.SrvMetering;
import com.aco.fatureapp.utilitary.Utils;

public class Printer2 {

	public Bluetooth mBth = new Bluetooth();

	public boolean closeBth() {
		if (mBth.isConnected()) {
			return mBth.Close();
		}
		return false;
	}

	public boolean checkBth(Context context, String macPrinter)
			throws Exception {

		if (!mBth.Enable()) {
			return false;
		}
		if (!mBth.connectPrinter(macPrinter)) {
			return false;
		}
		return true;
	}

	public static Bitmap gerarPrimeiraParte(Billing billing) {

		int eixoX = 0, eixoY = 0, width = 576;

		int size_text = 32, size_legend = 22;

		Paint fontTitleBold = new Paint(Color.BLACK);
		fontTitleBold.setTypeface(Typeface.create(Typeface.MONOSPACE,
				Typeface.BOLD));
		fontTitleBold.setTextSize((int) (size_text * 1.2));

		Paint fontLegend = new Paint(Color.BLACK);
		fontLegend.setTypeface(Typeface.create(Typeface.MONOSPACE,
				Typeface.NORMAL));
		fontLegend.setTextSize(size_legend);

		Paint fontLegend2 = new Paint(Color.BLACK);
		fontLegend2.setTypeface(Typeface.create(Typeface.MONOSPACE,
				Typeface.NORMAL));
		fontLegend2.setTextSize(size_legend);
		fontLegend2.setTextAlign(Align.RIGHT);

		Paint p = new Paint(Color.TRANSPARENT);
		p.setStyle(Style.STROKE);
		p.setStrokeWidth(2);

		Bitmap bitmapFatura = Bitmap.createBitmap(width, 1980, Config.RGB_565);

		Canvas canvas = new Canvas(bitmapFatura);

		canvas.drawColor(Color.WHITE);

		canvas.drawBitmap(bitmapFatura, 0, 0, p);

		eixoX = 30;
		eixoY += 270;

		canvas.drawText(billing.inscricao, 40, eixoY, fontTitleBold);

		canvas.drawText(billing.competencia, 410, eixoY + 6, fontTitleBold);

		eixoY += 80;
		canvas.drawText(billing.nomeCliente, eixoX, eixoY, fontLegend);

		eixoY += size_text;
		canvas.drawText(billing.endereco, eixoX, eixoY, fontLegend);

		eixoY += size_text;
		canvas.drawText(billing.bairro + " - " + billing.cidade + " - "
				+ billing.uf, eixoX, eixoY, fontLegend);

		eixoY += size_text;
		canvas.drawText(billing.leiturista, eixoX, eixoY, fontLegend);

		eixoY = 570;
		canvas.drawText(billing.classe, eixoX + 60, eixoY, fontLegend);

		canvas.drawText(billing.a_e, eixoX + 160, eixoY, fontLegend);

		eixoY = 600;
		canvas.drawText(billing.tarifa, eixoX + 50, eixoY, fontLegend);

		canvas.drawText(billing.economias, eixoX + 200, eixoY, fontLegend);

		eixoY += size_text;
		canvas.drawText(billing.localizacao, eixoX + 80, eixoY, fontLegend);

		eixoY += size_text + 25;
		canvas.drawText(billing.hidrometro, eixoX, eixoY, fontLegend);

		canvas.drawText(billing.dataInstalacao, eixoX + 200, eixoY, fontLegend);

		eixoY += size_text + 65;
		canvas.drawText("", eixoX, eixoY, fontLegend);

		canvas.drawText(billing.leituraAnterior, eixoX + 150, eixoY, fontLegend);

		eixoY += size_text + 22;
		canvas.drawText(billing.dataLeitura, eixoX, eixoY, fontLegend);

		canvas.drawText(billing.leituraAtual, eixoX + 150, eixoY, fontLegend);

		eixoY += size_text + 20;
		canvas.drawText(billing.diasConsumo, eixoX, eixoY, fontLegend);

		canvas.drawText(billing.consumo, eixoX + 150, eixoY, fontLegend);

		eixoY += size_text + 30;
		canvas.drawText(billing.media, eixoX + 90, eixoY - 20, fontLegend);

		canvas.drawText(billing.ocorrencia, eixoX + 290, eixoY, fontLegend);

		eixoY += size_text + 30;
		canvas.drawText(billing.mensagem1 != null ? billing.mensagem1 : "",
				eixoX, eixoY, fontLegend);

		eixoY += size_text;
		canvas.drawText(billing.mensagem2 != null ? billing.mensagem2 : "",
				eixoX, eixoY, fontLegend);

		eixoY += size_text;
		canvas.drawText(billing.mensagem3 != null ? billing.mensagem3 : "",
				eixoX, eixoY, fontLegend);

		eixoY += size_text;
		canvas.drawText(billing.mensagem4 != null ? billing.mensagem4 : "",
				eixoX, eixoY, fontLegend);

		Historic[] historics = billing.historics;

		eixoY = 615;

		for (int index = 1; index <= historics.length; index++) {

			Historic historic = historics[index - 1];

			canvas.drawText(historic.competencia != null ? historic.competencia
					: "", eixoX + 280, eixoY, fontLegend);

			canvas.drawText(historic.consumo != null ? historic.consumo : "",
					eixoX + 390, eixoY, fontLegend);

			canvas.drawText(historic.ocorrencia != null ? historic.ocorrencia
					: "", eixoX + 500, eixoY, fontLegend);

			eixoY += size_text;
		}

		eixoY = 1170;

		Paint fontLegendValor = new Paint(Color.BLACK);
		fontLegendValor.setTypeface(Typeface.create(Typeface.MONOSPACE,
				Typeface.NORMAL));
		fontLegendValor.setTextSize(14);
		fontLegendValor.setTextAlign(Align.RIGHT);

		Paint fontLegendMenor = new Paint(Color.BLACK);
		fontLegendMenor.setTypeface(Typeface.create(Typeface.MONOSPACE,
				Typeface.NORMAL));
		fontLegendMenor.setTextSize(14);

		Products[] products = billing.products;

		for (int index = 1; index <= products.length; index++) {

			Products product = products[index - 1];

			eixoY += size_text;
			canvas.drawText(
					product.codigo != null ? getZeroEsq(product.codigo, 5) : "",
					eixoX + 20, eixoY, fontLegendMenor);

			canvas.drawText(product.descricao != null ? product.descricao : "",
					eixoX + 80, eixoY, fontLegendMenor);

			canvas.drawText(product.parcela != null ? product.parcela : "",
					eixoX + 390, eixoY, fontLegendMenor);

			canvas.drawText(product.valor != null ? product.valor : "", 540,
					eixoY, fontLegendValor);
		}

		eixoY = 1585;

		Paint fontTitleBoldValor = new Paint(Color.BLACK);
		fontTitleBoldValor.setTypeface(Typeface.create(Typeface.MONOSPACE,
				Typeface.BOLD));
		fontTitleBoldValor.setTextAlign(Align.RIGHT);
		fontTitleBoldValor.setTextSize((int) (size_text * 1.2));

		canvas.drawText(billing.dataVencimento, 100, eixoY, fontTitleBoldValor);

		canvas.drawText(billing.totalConta, 545, eixoY, fontTitleBoldValor);

		eixoY = 1670;
		canvas.drawText(billing.multa, eixoX + 100, eixoY, fontLegend2);
		canvas.drawText(billing.valor, eixoX + 260, eixoY, fontLegend2);
		canvas.drawText(billing.jurosDiarios, eixoX + 480, eixoY, fontLegend2);

		eixoY = 1745;
		canvas.drawText(billing.reservatorio, eixoX + 110, eixoY, fontLegend);
		canvas.drawText(billing.dataColeta, eixoX + 390, eixoY, fontLegend);

		eixoY += size_text + 60;
		canvas.drawText(billing.reserCampo1, eixoX + 110, eixoY,
				fontLegendMenor);
		canvas.drawText(billing.reserCampo2, eixoX + 170, eixoY,
				fontLegendMenor);
		canvas.drawText(billing.reserCampo3, eixoX + 240, eixoY,
				fontLegendMenor);
		canvas.drawText(billing.reserCampo4, eixoX + 290, eixoY,
				fontLegendMenor);
		canvas.drawText(billing.reserCampo5, eixoX + 380, eixoY,
				fontLegendMenor);
		canvas.drawText(billing.reserCampo6, eixoX + 460, eixoY,
				fontLegendMenor);

		Bitmap primeiraParte = Bitmap.createBitmap(576, 1980, Config.RGB_565);

		Canvas g3 = new Canvas(primeiraParte);

		g3.drawBitmap(bitmapFatura, 0, 0, p);

		return primeiraParte;
	}

	public static Bitmap gerarSegundaParte(Billing billing) {

		int size_text = 20;

		int eixoX = 0, eixoY = 0;

		int w = 576, h = 850;

		Paint fontText = new Paint(Color.BLACK);
		fontText.setTypeface(Typeface.create(Typeface.SERIF, Typeface.NORMAL));
		fontText.setTextSize(size_text);

		Paint fontContaQuita = new Paint(Color.BLACK);
		fontContaQuita.setTypeface(Typeface.create(Typeface.SERIF,
				Typeface.NORMAL));
		fontContaQuita.setTextSize(40);

		Paint p = new Paint(Color.TRANSPARENT);
		p.setStyle(Style.STROKE);
		p.setStrokeWidth(0);

		Bitmap bitmapCodigoBarra = Bitmap.createBitmap(w, h, Config.ARGB_4444);

		Canvas canvas = new Canvas(bitmapCodigoBarra);

		canvas.drawColor(Color.WHITE);

		canvas.rotate(90, h / 2, h / 2);

		canvas.drawText(billing.inscricao, 120, 420, fontText);

		canvas.drawText(billing.codLeiturista, 430, 420, fontText);

		canvas.drawText(billing.nomeCliente, 150, 465, fontText);

		canvas.drawText(billing.numeroFatura, 45, 555, fontText);

		canvas.drawText(billing.competencia, 190, 555, fontText);

		canvas.drawText(billing.dataVencimento, 330, 555, fontText);

		canvas.drawText(billing.totalConta, 485, 555, fontText);

		if (billing.codigoBarras != null
				&& billing.codigoBarras.trim().length() > 0) {

			canvas.drawText(billing.codigoBarrasComDigito, 40, 730, fontText);

			BarI25 b25 = new BarI25();

			Bitmap i25 = b25.createI25(billing.codigoBarras);

			canvas.drawBitmap(i25, 20, h - 90, p);
		}
		else {
			canvas.drawText(billing.codigoBarrasComDigito, 40, 730,
					fontContaQuita);
		}

		// ------------------------------------------------
		Bitmap segundaParte = Bitmap.createBitmap(w, h, Config.RGB_565);

		Canvas canvasInvertido = new Canvas(segundaParte);

		canvasInvertido.drawBitmap(bitmapCodigoBarra, eixoX, eixoY, null);

		return segundaParte;
	}

	public static void imprimirResumo(Integer idRoteiro, Long idCarga,
			String imei, String competencia,
			List<PrinterResumo> lstPrinterResumo, OutputStream mOutStream)
			throws IOException {

		PrinterUtils mMobilePrint = new PrinterUtils(mOutStream);

		// por linha cabem 46 letras na fonte normal.

		imprimirCabecalhoResumo(idRoteiro, idCarga, imei, competencia,
				mMobilePrint);

		if (lstPrinterResumo != null && !lstPrinterResumo.isEmpty()) {

			mOutStream.flush();

			int quebra = 0;

			for (PrinterResumo printerResumo : lstPrinterResumo) {

				String hora = printerResumo.getHora();

				String linha = Utils.formartZeroLeft(
						printerResumo.getPosicao(), 3)
						+ " "
						+ Utils.formartZeroLeft(printerResumo.getInscricao(), 9)
						+ " "
						+ Utils.formartZeroLeft(printerResumo.getLeitura(), 7)
						+ " "
						+ hora
						+ "  "
						+ Utils.formartZeroLeft(printerResumo.getOcorrencia(),
								2)
						+ " "
						+ Utils.formartZeroLeft(printerResumo.getMatricula(), 6)
						+ " "
						+ printerResumo.getTipoEntrega()
						+ " "
						+ printerResumo.getRetida()
						+ " "
						+ printerResumo.getRefaturada();

				mMobilePrint.sendString(linha);

				mMobilePrint.printAndLineFeed();

				if (quebra == 65) {
					mOutStream.flush();
					SystemClock.sleep(5000);
					mMobilePrint.reset();

					imprimirCabecalhoResumo(idRoteiro, idCarga, imei,
							competencia, mMobilePrint);

					mOutStream.flush();
					SystemClock.sleep(1000);

					quebra = 0;
				}

				quebra++;
			}
		}

		mMobilePrint.printAndLineFeed();
		mMobilePrint.printAndLineFeed();
		mMobilePrint.printAndLineFeed();
		mMobilePrint.printAndLineFeed();
		mMobilePrint.printAndLineFeed();

		mMobilePrint.reset();

		mOutStream.flush();
		SystemClock.sleep(5000);
	}

	private static void imprimirCabecalhoResumo(Integer idRoteiro,
			Long idCarga, String imei, String competencia,
			PrinterUtils mMobilePrint) throws IOException {
		mMobilePrint.reset();

		// Buscar o black mark.
		mMobilePrint.goBlackMark();
		SystemClock.sleep(3000);

		mMobilePrint.sendDensity(6);
		mMobilePrint.printAndLineFeed();
		mMobilePrint.printAndLineFeed();
		mMobilePrint.printAndLineFeed();
		mMobilePrint.printAndLineFeed();
		mMobilePrint.printAndLineFeed();
		mMobilePrint.printAndLineFeed();

		mMobilePrint.sendString("ROTEIRO: "
				+ Utils.formartZeroLeft(idRoteiro, 3) + "  IMEI: " + imei);

		mMobilePrint.printAndLineFeed();

		mMobilePrint.sendString("ID_CARGA:" + idCarga + "  COMPETENCIA: "
				+ competencia);

		mMobilePrint.printAndLineFeed();

		mMobilePrint
				.sendString("P   INSCRICAO LEITURA HORA   OC MATRIC E R RF");

		mMobilePrint.printAndLineFeed();
	}

	public static void alinharImpressora(OutputStream mOutStream)
			throws IOException {

		PrinterUtils mMobilePrint = new PrinterUtils(mOutStream);

		// por linha cabem 46 letras na fonte normal.

		mMobilePrint.reset();

		// Buscar o black mark.
		mMobilePrint.goBlackMark();

		mMobilePrint.reset();

		mMobilePrint.setLineSpace(8);

		mMobilePrint.sendDensity(6);

		mMobilePrint.printAndLineFeed();
		mMobilePrint.printAndLineFeed();

		mOutStream.flush();

		SystemClock.sleep(1000);
	}

	public static void concluir(OutputStream mOutStream) throws IOException {

		PrinterUtils mMobilePrint = new PrinterUtils(mOutStream);

		// por linha cabem 46 letras na fonte normal.

		mMobilePrint.reset();

		mMobilePrint.setLineSpace(72);

		mMobilePrint.printAndLineFeed();

		mMobilePrint.setLineSpace(8);

		mOutStream.flush();

		SystemClock.sleep(1000);
	}

	public static void imprimirParteRapida(Billing billing,
			OutputStream mOutStream) throws IOException {

		PrinterUtils mMobilePrint = new PrinterUtils(mOutStream);

		// por linha cabem 46 letras na fonte normal.
		mMobilePrint.reset();

		// Buscar o black mark.
		mMobilePrint.goBlackMark();

		// Default 1mm(8dots)
		mMobilePrint.setLineSpace(32);
		mMobilePrint.printAndLineFeed();
		mMobilePrint.sendDensity(6);
		mMobilePrint.printAndLineFeed();
		mMobilePrint.printAndLineFeed();
		mMobilePrint.setPositionAbsolute(5);

		// width, height, bold, underline, minifont
		mMobilePrint.formatString(false, false, true, false, false);
		mMobilePrint.sendString(getEspacoDir(billing.inscricao, 18));

		mMobilePrint.sendString(getEspacoDir(billing.localizacao, 12));

		mMobilePrint.sendString(getEspacoEsq(billing.competencia, 12));
		mMobilePrint.printAndLineFeed();
		mMobilePrint.setLineSpace(48);
		mMobilePrint.printAndLineFeed();

		mMobilePrint.reset();
		mMobilePrint.reset();
		mMobilePrint.formatString(false, false, false, false, false);

		//
		mMobilePrint.setPositionAbsolute(2);
		mMobilePrint.sendString(getEspacoDir(billing.nomeCliente, 46));
		mMobilePrint.setLineSpace(8);
		mMobilePrint.printAndLineFeed();

		mMobilePrint.setPositionAbsolute(2);
		mMobilePrint.sendString(getEspacoDir(billing.endereco, 46));
		mMobilePrint.printAndLineFeed();

		mMobilePrint.setPositionAbsolute(2);
		mMobilePrint.sendString(getEspacoDir(billing.bairro, 46));
		mMobilePrint.printAndLineFeed();

		mMobilePrint.setPositionAbsolute(2);
		mMobilePrint.sendString(getEspacoDir(billing.cidade + "-" + billing.uf,
				46));
		mMobilePrint.printAndLineFeed();

		mMobilePrint.setPositionAbsolute(2);
		mMobilePrint.sendString(getEspacoDir(billing.leiturista, 46));
		mMobilePrint.printAndLineFeed();
		mMobilePrint.setLineSpace(8);
		mMobilePrint.printAndLineFeed();
		mMobilePrint.printAndLineFeed();
		mMobilePrint.printAndLineFeed();
		mMobilePrint.printAndLineFeed();
		mMobilePrint.printAndLineFeed();
		mMobilePrint.reset();

		mMobilePrint.setPositionAbsolute(10);
		mMobilePrint.sendString(getEspacoDir(billing.classe, 12));

		mMobilePrint.sendString(billing.a_e);
		mMobilePrint.printAndLineFeed();

		mMobilePrint.setPositionAbsolute(9);
		mMobilePrint.sendString(getEspacoDir(billing.tarifa, 14));

		Historic[] historics = billing.historics;

		mMobilePrint.sendString(billing.economias);

		// 1 linha do histório
		mMobilePrint.printAndLineFeed();
		mMobilePrint.reset();

		mMobilePrint.setPositionAbsolute(2);
		mMobilePrint.sendString(getEspacoEsq(billing.localizacao, 16));
		// 2 linha do histório
		printHistoric(historics, 1, 16, mMobilePrint);
		mMobilePrint.printAndLineFeed();

		// 3 linha do histório
		mMobilePrint.setPositionAbsolute(2);
		printHistoric(historics, 2, 32, mMobilePrint);
		mMobilePrint.setLineSpace(40);
		mMobilePrint.printAndLineFeed();

		// 4 linha do histório
		mMobilePrint.setPositionAbsolute(2);
		mMobilePrint.sendString(getEspacoDir(billing.hidrometro, 13));
		mMobilePrint.sendString(getEspacoDir(billing.dataInstalacao, 10));
		printHistoric(historics, 3, 9, mMobilePrint);
		mMobilePrint.setLineSpace(8);
		mMobilePrint.printAndLineFeed();
		mMobilePrint.reset();

		// 5 linha do histório
		mMobilePrint.setPositionAbsolute(2);
		printHistoric(historics, 4, 32, mMobilePrint);
		mMobilePrint.printAndLineFeed();

		// 6 linha do histório
		mMobilePrint.setPositionAbsolute(2);
		printHistoric(historics, 5, 32, mMobilePrint);
		mMobilePrint.setLineSpace(32);
		mMobilePrint.printAndLineFeed();

		// 7 linha do histório
		mMobilePrint.setPositionAbsolute(2);
		mMobilePrint.sendString(getEspacoDir(billing.dataLeituraAnterior, 15));
		mMobilePrint.sendString(getEspacoDir(billing.leituraAnterior, 4));
		printHistoric(historics, 6, 13, mMobilePrint);
		mMobilePrint.setLineSpace(8);
		mMobilePrint.printAndLineFeed();

		// 8 linha do histório
		mMobilePrint.setPositionAbsolute(2);
		printHistoric(historics, 7, 32, mMobilePrint);
		mMobilePrint.setLineSpace(32);
		mMobilePrint.printAndLineFeed();

		// 9 linha do histório
		mMobilePrint.setPositionAbsolute(2);
		mMobilePrint.sendString(getEspacoDir(billing.dataLeitura, 15));
		mMobilePrint.sendString(getEspacoDir(billing.leituraAtual, 4));
		printHistoric(historics, 8, 13, mMobilePrint);
		mMobilePrint.setLineSpace(32);
		mMobilePrint.printAndLineFeed();

		mMobilePrint.setPositionAbsolute(2);
		mMobilePrint.printAndLineFeed();
		mMobilePrint.setPositionAbsolute(4);
		mMobilePrint.sendString(getEspacoDir(billing.diasConsumo, 10));
		mMobilePrint.sendString(getEspacoEsq(billing.consumo, 8));
		mMobilePrint.printAndLineFeed();
		mMobilePrint.reset();
		mMobilePrint.setLineSpace(24); // /
		mMobilePrint.printAndLineFeed();
		mMobilePrint.reset();

		// begin line
		mMobilePrint.reset();
		mMobilePrint.setLineSpace(8); // /
		mMobilePrint.setPositionAbsolute(12);
		mMobilePrint.sendString(getEspacoDir(billing.media, 20));
		mMobilePrint.sendString(getEspacoDir(billing.ocorrencia, 18));
		mMobilePrint.printAndLineFeed();
		mMobilePrint.printAndLineFeed();
		mMobilePrint.printAndLineFeed();
		mMobilePrint.reset();
		mMobilePrint.setLineSpace(16); // /
		mMobilePrint.printAndLineFeed();
		mMobilePrint.reset();
		// end line

		mMobilePrint.setPositionAbsolute(2);
		mMobilePrint.sendString(getEspacoDir(billing.mensagem1, 46));
		mMobilePrint.setLineSpace(8);
		mMobilePrint.printAndLineFeed();
		mMobilePrint.reset();

		mMobilePrint.setPositionAbsolute(2);
		mMobilePrint.sendString(getEspacoDir(billing.mensagem2, 46));
		mMobilePrint.printAndLineFeed();
		mMobilePrint.reset();

		mMobilePrint.setPositionAbsolute(2);
		mMobilePrint.sendString(getEspacoDir(billing.mensagem3, 46));
		mMobilePrint.printAndLineFeed();
		mMobilePrint.reset();

		mMobilePrint.setPositionAbsolute(2);
		mMobilePrint.sendString(getEspacoDir(billing.mensagem4, 46));
		mMobilePrint.setLineSpace(24);
		mMobilePrint.printAndLineFeed();
		mMobilePrint.reset();

		mMobilePrint.printAndLineFeed();
		mMobilePrint.setLineSpace(8);
		mMobilePrint.reset();

		Products[] products = billing.products;

		for (int index = 1; index <= 8; index++) {

			Products product = products[index - 1];

			if (product.codigo == null || product.codigo.trim().length() == 0) {
				mMobilePrint.sendString(getEspacoDir("", 2));
				mMobilePrint.printAndLineFeed();
				mMobilePrint.reset();
			}
			else {
				mMobilePrint.sendString(getEspacoEsq(product.codigo, 5));
				mMobilePrint.sendString(getEspacoDir("", 2));
				mMobilePrint.sendString(getEspacoDir(product.descricao, 22));
				mMobilePrint.sendString(getEspacoDir("", 2));
				mMobilePrint.sendString(getEspacoEsq(product.parcela, 5));
				mMobilePrint.sendString(getEspacoDir("", 2));
				mMobilePrint.sendString(getEspacoEsq(product.valor, 10));
				mMobilePrint.printAndLineFeed();
				mMobilePrint.reset();
			}

			// if (index == products.length) {
			// mMobilePrint.printAndLineFeed();
			// }
		}

		// width, height, bold, underline, minifont
		// begin line
		mMobilePrint.setLineSpace(24);
		mMobilePrint.printAndLineFeed();

		mMobilePrint.formatString(false, true, true, false, false);
		mMobilePrint.setPositionAbsolute(19);
		mMobilePrint.sendString(getEspacoDir(billing.dataVencimento, 23));
		mMobilePrint.sendString(billing.totalConta);
		mMobilePrint.printAndLineFeed();
		mMobilePrint.reset();
		// end line

		mMobilePrint.setLineSpace(24);
		mMobilePrint.printAndLineFeed();

		// begin line
		mMobilePrint.formatString(false, false, false, false, false);
		mMobilePrint.setPositionAbsolute(9);
		mMobilePrint.sendString(getEspacoDir(billing.multa + "%", 14));
		mMobilePrint.sendString(getEspacoDir(billing.valor, 18));
		mMobilePrint.sendString(getEspacoDir(billing.jurosDiarios, 7));
		mMobilePrint.printAndLineFeed();
		mMobilePrint.reset();
		// end line

		mMobilePrint.setLineSpace(32);

		mMobilePrint.printAndLineFeed();

		mMobilePrint.setPositionAbsolute(16);
		mMobilePrint.sendString(getEspacoDir(billing.reservatorio, 29));
		mMobilePrint.sendString(getEspacoDir(billing.dataColeta, 8));
		mMobilePrint.setLineSpace(76);
		mMobilePrint.printAndLineFeed();

		mMobilePrint.reset();

		mMobilePrint.setPositionAbsolute(14);
		mMobilePrint.sendString(getEspacoDir(billing.reserCampo1, 7));
		mMobilePrint.sendString(getEspacoDir(billing.reserCampo2, 6));
		mMobilePrint.sendString(getEspacoDir(billing.reserCampo3, 5));
		mMobilePrint.sendString(getEspacoDir(billing.reserCampo4, 7));
		mMobilePrint.sendString(getEspacoDir(billing.reserCampo5, 8));
		mMobilePrint.sendString(getEspacoDir(billing.reserCampo6, 3));
		mMobilePrint.printAndLineFeed();
		mMobilePrint.setLineSpace(16);
		mMobilePrint.printAndLineFeed();
		mMobilePrint.printAndLineFeed();

		mMobilePrint.reset();

		// Escrever conteudo na impressora.
		mOutStream.flush();

		SystemClock.sleep(5000);
	}

	private static void printHistoric(Historic[] historics, int index,
			int tamPrimeiraColuna, PrinterUtils mMobilePrint)
			throws IOException {
		Historic historic = historics[index - 1];
		mMobilePrint.sendString(getEspacoEsq(historic.competencia,
				tamPrimeiraColuna));
		mMobilePrint.sendString(getEspacoEsq(historic.consumo, 7));
		mMobilePrint.sendString(getEspacoEsq(historic.ocorrencia, 6));
	}

	/**
	 * Método que inclui espaços em uma string caso ela tenha menos caracteres
	 * que o especificado
	 */
	public static String getEspacoDir(String palavra,
			final Integer tamanhoMaximo) {
		if (palavra == null) {
			palavra = " ";
		}

		int tamanho = palavra.length();
		if (tamanho > tamanhoMaximo) {
			return palavra.substring(0, tamanhoMaximo);
		}

		if (tamanho < tamanhoMaximo) {
			for (int i = tamanho; i < tamanhoMaximo; i++) {
				// Adicionando espaço ao início da String
				palavra = palavra.concat(" ");
			}
		}
		return palavra;
	}

	public static String getEspacoEsq(String palavra,
			final Integer tamanhoMaximo) {
		if (palavra == null) {
			palavra = " ";
		}

		int tamanho = palavra.length();
		if (tamanho < tamanhoMaximo) {
			for (int i = tamanho; i < tamanhoMaximo; i++) {
				// Adicionando espaço ao início da String
				palavra = " ".concat(palavra);
			}
		}
		return palavra;
	}

	public static Integer getPosicao(String palavra, final Integer tamanhoMaximo) {

		if (palavra == null) {
			return 0;
		}

		return tamanhoMaximo - palavra.length();
	}

	public static String getZeroEsq(String palavra, final Integer tamanhoMaximo) {
		if (palavra == null) {
			return palavra = "";
		}

		int tamanho = palavra.length();
		if (tamanho < tamanhoMaximo) {
			for (int i = tamanho; i < tamanhoMaximo; i++) {
				// Adicionando espaço ao início da String
				palavra = "0".concat(palavra);
			}
		}
		return palavra;
	}

	public static List<List<Products>> quebrarFaturaEmPaginas(
			List<Products> lstProdutos) {

		int tamanhoDosProdutos = 8;

		List<List<Products>> listas = new ArrayList<List<Products>>();

		if (lstProdutos != null && !lstProdutos.isEmpty()) {

			int numeroBlocos = lstProdutos.size() / 8;
			int restante = lstProdutos.size() % 8;
			int somaProdutos = 0;

			for (int i = 0; i < numeroBlocos; i++) {
				List<Products> lstAuxiliar = new ArrayList<Products>(
						lstProdutos.subList(somaProdutos, tamanhoDosProdutos
								+ somaProdutos));

				listas.add(lstAuxiliar);
				somaProdutos += tamanhoDosProdutos;
			}
			/*
			 * Pegando o restante da lista ou se ela chegou no método com menos
			 * de 8 itens vai lista todos.
			 */
			if (restante > 0) {
				List<Products> lstAuxiliar = new ArrayList<Products>(
						lstProdutos.subList(somaProdutos, somaProdutos
								+ restante));

				listas.add(lstAuxiliar);
			}
		}
		return listas;
	}

	private static void imprimirUmaConta(final String macPrinter,
			Billing billing, Context context, Printer2 mPrinter,
			Long inscricao, LogLeitura mLogLeitura) throws Exception {
		if (mPrinter.checkBth(context, macPrinter)) {

			Printer2.imprimirParteRapida(billing, mPrinter.mBth.ostream);

			Bitmap segundaParte = Printer2.gerarSegundaParte(billing);

			ESCP.ImageToEsc(segundaParte, mPrinter.mBth.ostream, 8, 10);

			Integer marcarQtdImpressao = new SrvMetering()
					.marcarQtdImpressao(inscricao);

			if (mLogLeitura != null && marcarQtdImpressao != null) {
				mLogLeitura.setQtdeImpressao(marcarQtdImpressao.longValue());
			}
		}

		mPrinter.closeBth();
	}

	public static void imprimirContaEmPaginas(final String macPrinter,
			Billing billing, Context context, Printer2 mPrinter,
			Long inscricao, LogLeitura mLogLeitura) throws Exception {
		List<List<Products>> lstPaginas = Printer2
				.quebrarFaturaEmPaginas(Arrays.asList(billing.products));

		if (lstPaginas != null && !lstPaginas.isEmpty()) {
			if (lstPaginas.size() == 1) {

				List<Products> lstProdutos = new ArrayList<Products>(
						Arrays.asList(billing.getProducts()));

				preencherLinhaProdutos(lstProdutos);

				billing.setProducts(lstProdutos.toArray(lstProdutos
						.toArray(new Products[lstProdutos.size()])));

				imprimirUmaConta(macPrinter, billing, context, mPrinter,
						inscricao, mLogLeitura);
			}
			else {

				/*
				 * Verificar se não é a última página para imprimir "*" no campo
				 * valor e não imprimir os códigos de barras.
				 */
				String codigoBarras = billing.getCodigoBarras();
				String codigoBarrasComDigito = billing
						.getCodigoBarrasComDigito();
				String valorConta = billing.getTotalConta();

				// Setar os campos como nulos.
				billing.setCodigoBarras(null);
				billing.setCodigoBarrasComDigito("");
				billing.setTotalConta("**********");

				for (int index = 0; index < lstPaginas.size(); index++) {

					List<Products> paginas = lstPaginas.get(index);

					// Quando for a última página setar os
					// valores dos campos de volta.
					if (index == (lstPaginas.size() - 1)) {
						billing.setCodigoBarras(codigoBarras);
						billing.setCodigoBarrasComDigito(codigoBarrasComDigito);
						billing.setTotalConta(valorConta);

						preencherLinhaProdutos(paginas);
					}

					billing.setProducts(paginas.toArray(new Products[paginas
							.size()]));

					imprimirUmaConta(macPrinter, billing, context, mPrinter,
							inscricao, mLogLeitura);

					SystemClock.sleep(1000);
				}
			}
		}
	}

	private static void preencherLinhaProdutos(List<Products> paginas) {
		// Deixar sempre a lista de produtos
		// com 8 elementos.
		int resto = 8 - paginas.size();

		for (int i = 1; i <= resto; i++) {
			paginas.add(getProdutoEmBranco());
		}
	}

	private static Products getProdutoEmBranco() {
		return new Products();
	}

}
